package com.alibaba.citrus.cr.order.open.api.facade.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.common.lock.RedisLock;
import com.alibaba.citrus.cr.order.open.api.facade.common.contant.PlanStatusEnum;
import com.alibaba.citrus.cr.order.open.api.facade.common.until.CheckUtil;
import com.alibaba.citrus.cr.unified.inventory.facade.service.AllocateApplyOrderReadServiceImpl;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.contants.BcOrderConstants;
import com.epoch.app.mninventorycenter.model.dto.*;
import com.epoch.app.mninventorycenter.planorderwriteservice.service.PlanOrderWriteServiceService;
import com.epoch.app.mninventorycenter.service.MnInventoryCenterService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class PlanOrderWriteServiceServiceImpl implements PlanOrderWriteServiceService {

    Log log = Log.getLogger(AllocateApplyOrderReadServiceImpl.class);

    @Resource
    MnInventoryCenterService mnInventoryCenterService;

    private static final String FROM_SYS_GROUP = "fromSys";
    private static final String BUSINESS_TYPE_GROUP = "businessType";

    @Override
    @FacadeInvoker(value = "创建计划单")
    public Result<Boolean> createPlanOrder(BusinessPlanOrderCreateRequest businessPlanOrderCreateRequest) {

        log.info("PlanOrderWriteServiceService.createPlanOrder.businessPlanOrderCreateRequest:{}", JSONObject.toJSONString(businessPlanOrderCreateRequest));
        String message = checkPlanOrderCreateRequest(businessPlanOrderCreateRequest);
        if(message != null){
            return Result.fail("10000",message);
        }
        List<ScItemResponse> scItemInfoList = getScItemInfoList(Collections.singletonList(businessPlanOrderCreateRequest.getGoodsCode()));
        // 货品状态，类型校验
        String checkScItemTypeAndStatusList = CheckUtil.getCheckScItemTypeAndStatusList(scItemInfoList);

        if(checkScItemTypeAndStatusList !=null ){
            return Result.fail("10003",checkScItemTypeAndStatusList);
        }
        String key = businessPlanOrderCreateRequest.getFactoryCode()+"_"+
                businessPlanOrderCreateRequest.getGoodsCode()+"_"+
                businessPlanOrderCreateRequest.getPlanDate()+"_"+
                businessPlanOrderCreateRequest.getBusinessType()+"_"+
                businessPlanOrderCreateRequest.getUnit();
        try (RedisLock lock = new RedisLock(BcOrderConstants.REDIS_CACHE_CODE(),
                "createPlanOrder_" + key,
                5000,10000)){
            Result<Long> result = mnInventoryCenterService.createPlanOrder(businessPlanOrderCreateRequest);
            log.info("PlanOrderWriteServiceService.createPlanOrder.response:{}", JSONObject.toJSONString(result));
            if(!result.isSuccess()){
                return Result.fail(false,result.getErrorCode(),result.getMessage());
            }
            return Result.success(result.getResult() > 0);
        }catch (Throwable e) {
            log.error("PlanOrderWriteServiceService_createPlanOrder_error req:{} ", JSON.toJSON(businessPlanOrderCreateRequest));
            log.error("create createPlanOrder error", e);
        }

        return Result.fail("10007","计划单创建失败");
    }

    private String checkPlanOrderCreateRequest(BusinessPlanOrderCreateRequest planOrderCreateRequest) {

        if(StringUtils.isBlank(planOrderCreateRequest.getFactoryCode())){
            return "工厂编码参数不能为空";
        }
        if(planOrderCreateRequest.getFactoryCode().length() >32){
            return "工厂编码参数长度不能超过32";
        }
        if(StringUtils.isBlank(planOrderCreateRequest.getGoodsCode()) ){
            return "货品编码参数不能为空";
        }
        if(planOrderCreateRequest.getGoodsCode().length() >32){
            return "货品编码参数长度不能超过32";
        }
        if(ObjectUtil.isEmpty(planOrderCreateRequest.getPlanDate())){
            return "计划日期能参数不能为空";
        }
        if(StringUtils.isBlank(planOrderCreateRequest.getUnit())){
            return "单位编码参数不能为空";
        }
        if(planOrderCreateRequest.getUnit().length() >32){
            return "单位编码参数长度不能超过32";
        }
        if(StringUtils.isBlank(planOrderCreateRequest.getBusinessType())){
            return "业态参数不能为空";
        }
        if(planOrderCreateRequest.getBusinessType().length() >32){
            return "业态参数长度不能超过32";
        }
        if(StringUtils.isBlank(planOrderCreateRequest.getFromSys())){
            return "系统来源参数不能为空";
        }
        if(planOrderCreateRequest.getFromSys().length() >32){
            return "系统来源参数长度不能超过32";
        }

        if (!checkDictionary(FROM_SYS_GROUP,planOrderCreateRequest.getFromSys())){
            return "系统来源错误";
        }
        if (!checkDictionary(BUSINESS_TYPE_GROUP,planOrderCreateRequest.getBusinessType())){
            return "业态错误";
        }
        return null;

    }
    /**
     * 校验字典
     * @param group group
     * @param code code
     * @return boolean
     */
    private boolean checkDictionary(String group, String code) {
        DictionaryQueryRequest request = new DictionaryQueryRequest();
        request.setGroup(group);
        log.info("checkDictionary,group:{},code:{}",group,code);
        Result<List<DictionaryResponse>> result = mnInventoryCenterService.queryDictionaryDataListApi(request);
        log.info("checkDictionary,result:{}",JSON.toJSON(result));
        Set<String> businessTypeSet = result.getResult().stream()
                .map(DictionaryResponse::getCode)
                .collect(Collectors.toSet());
        return businessTypeSet.contains(code);
    }



    @Override
    @FacadeInvoker(value = "更新计划单")
    public Result<Boolean> updatePlanOrderQuantity(BusinessPlanOrderUpdateRequest businessPlanOrderUpdateRequest) {
        log.info("PlanOrderWriteServiceService.updatePlanOrderQuantity.businessPlanOrderUpdateRequest.request:{}", JSONObject.toJSONString(businessPlanOrderUpdateRequest));
        String message = checkUpdatePlanOrderQuantity(businessPlanOrderUpdateRequest);
        if(message !=null ){
            return Result.fail("10000",message);
        }
        List<ScItemResponse> scItemInfoList = getScItemInfoList(Collections.singletonList(businessPlanOrderUpdateRequest.getGoodsCode()));
        String checkScItemTypeAndStatusList = CheckUtil.getCheckScItemTypeAndStatusList(scItemInfoList);

        if(checkScItemTypeAndStatusList !=null ){
            return Result.fail("10003",checkScItemTypeAndStatusList);
        }
        BusinessPlanOrderUpdateRequest updateRequest = new BusinessPlanOrderUpdateRequest();
        updateRequest.setPlanQuantity(businessPlanOrderUpdateRequest.getPlanQuantity());
        updateRequest.setStatus(businessPlanOrderUpdateRequest.getStatus());
        updateRequest.setUnit(businessPlanOrderUpdateRequest.getUnit());
        updateRequest.setGoodsCode(businessPlanOrderUpdateRequest.getGoodsCode());
        updateRequest.setFactoryCode(businessPlanOrderUpdateRequest.getFactoryCode());
        updateRequest.setPlanDate(businessPlanOrderUpdateRequest.getPlanDate());
        log.info("createPlanOrder_updatePlanOrderQuantity,updatePlanOrderQuantity,request:{}",JSON.toJSON(updateRequest));
        Result<Boolean> booleanResult = mnInventoryCenterService.updatePlanOrderQuantity(updateRequest);
        log.info("createPlanOrder_updatePlanOrderQuantity,updatePlanOrderQuantity,booleanResult:{}",JSON.toJSON(booleanResult));
        if(booleanResult.isSuccess()){
            return booleanResult;
        }
        return Result.fail("10010",booleanResult.getMessage());
    }

    private Date strTODate(String str)  {
        SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return df.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    private String checkUpdatePlanOrderQuantity(BusinessPlanOrderUpdateRequest businessPlanOrderUpdateRequest) {

        if(StrUtil.isBlank(businessPlanOrderUpdateRequest.getUnit())){
            return "单位不可以为空";
        }
        String unit = businessPlanOrderUpdateRequest.getUnit().trim();
        if (StrUtil.isBlank(unit)) {
            return "单位不可以为空";
        }
        businessPlanOrderUpdateRequest.setUnit(unit);
        if(businessPlanOrderUpdateRequest.getUnit().length() >32){
            return "单位参数长度不能超过32";
        }
        if (StrUtil.isBlank(businessPlanOrderUpdateRequest.getGoodsCode())){
            return "商品编码不可以为空";
        }
        String goodsCode = businessPlanOrderUpdateRequest.getGoodsCode().trim();
        if (StrUtil.isBlank(goodsCode)) {
            return "商品编码不可以为空";
        }
        businessPlanOrderUpdateRequest.setGoodsCode(goodsCode);
        if(businessPlanOrderUpdateRequest.getGoodsCode().length() >32){
            return "商品编码参数长度不能超过32";
        }
        if (StrUtil.isBlank(businessPlanOrderUpdateRequest.getFactoryCode())){
            return "工厂编码不可以为空";
        }
        String factoryCode = businessPlanOrderUpdateRequest.getFactoryCode().trim();
        if (StrUtil.isBlank(factoryCode)) {
            return "工厂编码不可以为空";
        }
        businessPlanOrderUpdateRequest.setFactoryCode(factoryCode);
        if (businessPlanOrderUpdateRequest.getFactoryCode().length() > 32){
            return "工厂编码参数长度不能超过32";
        }
        if (StringUtils.isBlank(businessPlanOrderUpdateRequest.getPlanDate())){
            return "计划时间不可以为空";
        }
        String planDate = businessPlanOrderUpdateRequest.getPlanDate().trim();
        if (StringUtils.isBlank(planDate)) {
            return "计划时间不可以为空";
        }
        businessPlanOrderUpdateRequest.setPlanDate(planDate);
        if (businessPlanOrderUpdateRequest.getPlanDate().length() != 19) {
            return "计划时间参数长度为19";
        }
        if (!CheckUtil.isLegalDate(businessPlanOrderUpdateRequest.getPlanDate())){
            return "计划时间参数格式不合法";
        }

        if (ObjectUtil.isNull(businessPlanOrderUpdateRequest.getStatus())
            || ObjectUtil.isNull(businessPlanOrderUpdateRequest.getPlanQuantity())){
            return "是否关闭或计划量异常";
        }
        //是否关闭：1:代表启用，2:代表关闭，默认1
        if(ObjectUtil.isNull(businessPlanOrderUpdateRequest.getStatus())){
            return "是否关闭不能为空";
        }
        PlanStatusEnum byType = PlanStatusEnum.getByType(businessPlanOrderUpdateRequest.getStatus());
        if(byType == null){
            return "是否关闭不合法";
        }
        if (ObjectUtil.isNull(businessPlanOrderUpdateRequest.getPlanQuantity())){
            return "计划量不能为空";
        }
        return null;
    }
    /**
     * 通过货品外部编码（goodsCode）查询货品详情goodsInfo(scItem)  getScItemInfoList
     */
    public List<ScItemResponse> getScItemInfoList(List<String> outerIdList){
        if(CollectionUtils.isEmpty(outerIdList)){
            return null;
        }
        ScItemSearchReqAbilityDTO scItemSearchReqAbilityDTO1 = new ScItemSearchReqAbilityDTO();
        scItemSearchReqAbilityDTO1.setOuterIdList(outerIdList);
        Result<List<ScItemResponse>> listResult = mnInventoryCenterService.searchScItemFromDbList(scItemSearchReqAbilityDTO1);

        List<ScItemResponse> result = listResult.getResult();
        if(CollectionUtil.isEmpty(result)){
            return null;
        }
        return result;
    }

}
